package com.mapperdb.helper;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.scripting.xmltags.IfSqlNode;
import org.apache.ibatis.scripting.xmltags.MixedSqlNode;
import org.apache.ibatis.scripting.xmltags.SqlNode;
import org.apache.ibatis.scripting.xmltags.StaticTextSqlNode;

import com.mapperdb.mapping.Result;
import com.mapperdb.util.MapperUtils;

/**
 * Mapper 模板类
 * @author Administrator
 *
 */
public class MapperTemplate {
	public static final Map<String, ResultEntity> resultEntityMap = new HashMap<String, ResultEntity>();

	/**
	 * 获取所有列的where节点中的if判断列
	 *
	 * @param entityClass
	 * @return
	 */
	protected SqlNode getAllIfColumnNode(ResultEntity resultEntity) {
		List<SqlNode> ifNodes = new ArrayList<SqlNode>();
		//获取全部列
		List<Result> results = resultEntity.getResults();
		//对所有列循环，生成<if test="property!=null">column = #{property}</if>
		for (Result column : results) {
			ifNodes.add(getIfNotNull(column, getColumnEqualsProperty(column)));
		}
		return new MixedSqlNode(ifNodes);
	}

	/**
	 * 获取所有列的where节点中的if判断列
	 *
	 * @param entityClass
	 * @return
	 */
	protected SqlNode getPrimaryKeyColumnNode(ResultEntity resultEntity) {
		List<SqlNode> ifNodes = new ArrayList<SqlNode>();
		//获取全部列
		List<Result> results = resultEntity.getResults();
		//对所有列循环，生成<if test="property!=null">column = #{property}</if>
		for (Result column : results) {
			if (column.isId()) ifNodes.add(getIfNotNull(column, getColumnEqualsProperty(column)));
		}
		return new MixedSqlNode(ifNodes);
	}

	/**
	 * 返回if条件的sqlNode
	 * <p>一般类型：<code>&lt;if test="property!=null"&gt;columnNode&lt;/if&gt;</code></p>
	 *
	 * @param column
	 * @param columnNode
	 * @param empty      是否包含!=''条件
	 * @return
	 */
	protected SqlNode getIfNotNull(Result result, SqlNode columnNode) {
		return new IfSqlNode(columnNode, result.getProperty() + " != null");
	}

	/**
	 * 获取 <code>AND column = #{property}</code>
	 *
	 * @param column
	 * @param first
	 * @return
	 */
	protected SqlNode getColumnEqualsProperty(Result result) {
		return new StaticTextSqlNode(" AND " + result.formatEqualsColumn());
	}

	/**
	 * @author Administrator
	 */
	protected static class ResultEntity {
		protected String tableName;
		protected List<Result> results;
		protected Class<?> entityClass;

		public String getTableName() {
			return tableName;
		}

		public List<Result> getResults() {
			return results;
		}

		public Class<?> getEntityClass() {
			return entityClass;
		}

		public String getInsertColumns() {
			StringBuffer sb = new StringBuffer();
			boolean flag = false;
			for (Result result : results) {
				if (!result.isBefore()) continue;// not before selectKey

				if (flag) sb.append(" , ");

				flag = true;
				sb.append(result.getColumn());
			}
			return sb.toString();
		}

		public String getSelectColumns() {
			StringBuffer sb = new StringBuffer();
			boolean flag = true;
			for (Result result : results) {
				if (!flag) sb.append(" , ");
				sb.append(result.getColumn()).append(" AS ").append(result.getProperty());
				flag = false;

			}
			return sb.toString();
		}

		protected void init(String id) {
			this.entityClass = MapperUtils.getGenericType(id);
			this.results = MapperUtils.getResults(entityClass);
			this.tableName = MapperUtils.getTableName(entityClass);
		}
	}

	protected static ResultEntity getResultEntity(String id) {
		ResultEntity resultEntity = resultEntityMap.get(id);
		if (resultEntity == null) {
			synchronized (resultEntityMap) {
				if (resultEntity == null) {
					resultEntity = new ResultEntity();
					resultEntity.init(id);
					resultEntityMap.put(id, resultEntity);
				}
			}
		}
		return resultEntity;
	}
}
